package com.lie.flat.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.Gson;
import com.lie.flat.constant.CommonConst;
import com.lie.flat.entity.ApplyRequest;
import com.lie.flat.entity.ApplyRequestEs;
import com.lie.flat.entity.ApplyResponse;
import com.lie.flat.service.ApplyRequestService;
import com.lie.flat.service.connect.ApplyService;
import com.lie.flat.util.CommonReturn;
import com.lie.flat.util.DateUtils;
import com.lie.flat.util.IdempotentUtils;
import com.lie.flat.util.ValidatorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.elasticsearch.action.bulk.BulkProcessor;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.List;


@Slf4j
@RestController
@RequestMapping("/apply")
public class ApplyController {
    @Autowired
    @Qualifier(value = "default es client")
    RestHighLevelClient client;

    @Autowired
    @Qualifier(value = "bulk processor")
    private BulkProcessor bulkProcessor;
    @Autowired
    private ApplyService applyService;

    @Autowired
    private ApplyRequestService applyRequestService;

    /**
     * 发送申请人信息，调用第三方接口返回申请结果并存入数据库
     *
     * @param applyRequest
     * @return
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    @PostMapping("/person")
    @CrossOrigin
    public CommonReturn savePerson(@RequestBody ApplyRequest applyRequest) {
        //接收申请信息
        String idNo = applyRequest.getIDNo();
        String serialNo = RandomStringUtils.randomAlphanumeric(20);
        applyRequest.setSerialNo(serialNo);

        //防重复提交
        if (!IdempotentUtils.judge(IdempotentUtils.localCache, idNo)) {
            return CommonReturn.error("请勿重复提交");
        }

        //如果姓名为空，返回错误
        if (applyRequest.getName() == null || applyRequest.getName().isEmpty()) {
            return CommonReturn.error("姓名不能为空！");
        }
        //如果身份证为空或者不是18位，返回错误
        if (!ValidatorUtils.isLegalIdNo(applyRequest.getIDNo())) {
            return CommonReturn.error("身份证信息输入错误！");
        }

        //如果年龄小于18岁或者大于65岁，则申请失败
        if (!ValidatorUtils.getAge(applyRequest.getIDNo())){
            return CommonReturn.error("您的年龄不符合申请要求！");
        }

        applyRequest.setSysId("addd");
        applyRequest.setPasswd("2wsx#EDC");
        ApplyResponse applyResponse = applyService.jsonReqApply(applyRequest);
        //如果范围的Response的code不是C0001，返回具体错误msg
        if (!applyResponse.getCode().equals("C0001")) {
            return CommonReturn.error(applyResponse.getMessage());
        }

        //查询该申请信息的身份证号和手机号是否存在于数据库，如果存在返回错误
        QueryWrapper<ApplyRequest> queryWrapper = new QueryWrapper<>();
        int count = applyRequestService.count(queryWrapper.eq("i_d_no", applyRequest.getIDNo()));

        if (count > 0) {
            return CommonReturn.error("您已申请过信用卡！");
        }

        //随机生成卡号并将申请人信息存入数据库
        StringBuilder stringBuilder = new StringBuilder();
        StringBuilder append = stringBuilder
                .append(Math.round(Math.random() * 900000000 + 100000000))
                .append(Math.round(Math.random() * 900000000 + 100000000));
        String cardNum = append.toString();
        applyRequest.setPasswd("*******");
        applyRequest.setCardNum(cardNum);

        applyRequestService.save(applyRequest);
        asyncSave2Es(applyRequest); //async save to es
        return CommonReturn.success(applyResponse);

    }

    /**
     * 异步存es
     */
    private void asyncSave2Es(ApplyRequest src) {

        if (!isExistsIndex(client, CommonConst.INDEX_NAME)) {
            CreateIndexRequest createIdxReq = new CreateIndexRequest(CommonConst.INDEX_NAME);
            CreateIndexResponse createIndexResponse = null;
            try {
                createIndexResponse = client.indices().create(createIdxReq, RequestOptions.DEFAULT);
                boolean acknowledged = createIndexResponse.isAcknowledged();
                if (acknowledged) {
                    log.info("created new index {}", CommonConst.INDEX_NAME);
                }
            } catch (IOException e) {
                log.error("create index {} error", CommonConst.INDEX_NAME, e);
            }
        }
        ApplyRequestEs target = new ApplyRequestEs();
        BeanUtils.copyProperties(src, target);
        Date date = DateUtils.str2Date(src.getReqTime());
        target.setReqTime(date);
        IndexRequest indexRequest = new IndexRequest(CommonConst.INDEX_NAME);
        Gson gson = new Gson();
        bulkProcessor.add(indexRequest.source(gson.toJson(target), XContentType.JSON));
    }

    // 判断该es索引是否存在, 不存在则创建
    private static boolean isExistsIndex(RestHighLevelClient client, String index) {
        GetIndexRequest indexRequest = new GetIndexRequest(index);
        boolean exists = false;
        try {
            exists = client.indices().exists(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            log.error("判断索引是否存在时出现问题", e);
        }
        return exists;
    }
    /**
     * 根据身份证和手机号查询申请人信息
     *
     * @param applyRequest
     * @return
     */
    @PostMapping("/status")
    @CrossOrigin
    public CommonReturn getStatus1(@RequestBody ApplyRequest applyRequest) {

        if (!ValidatorUtils.isLegalIdNo(applyRequest.getIDNo())) {
            return CommonReturn.error("身份证信息输入错误！");
        }
        QueryWrapper<ApplyRequest> applyRequestQueryWrapper = new QueryWrapper<>();
        QueryWrapper<ApplyRequest> eq1 = applyRequestQueryWrapper.eq("i_d_no", applyRequest.getIDNo());
        List<ApplyRequest> list = applyRequestService.list(eq1);

        int count = applyRequestService.count(eq1);
        if (count == 0) {
            return CommonReturn.error("申请失败!");
        }

        return CommonReturn.success(list);
    }


}
